package org.ktx.osr.audio

import android.Manifest
import android.content.Context
import android.media.AudioAttributes
import android.media.AudioFormat
import android.media.AudioPlaybackCaptureConfiguration
import android.media.AudioRecord
import android.media.MediaRecorder
import android.media.projection.MediaProjection
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresPermission
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.launch
import org.ktx.osr.ui.AppSettings
import java.io.File

/**
 * 系统音频录制器
 * 负责系统音频的录制，支持AAC和WAV格式输出
 * 功能边界：仅负责音频录制，不处理编码和文件操作的具体实现
 */
class SystemAudioRecorder(
    private val context: Context,
    private val settings: AppSettings,
    private val mediaProjection: MediaProjection
) {
    private var audioRecord: AudioRecord? = null
    private var isRecording = false
    private var recordingJob: Job? = null
    private var audioFile: File? = null
    private var audioEncoder: AudioEncoder? = null
    private var wavFileHandler: WavFileHandler? = null
    private var config: AudioRecordingConfig? = null

    companion object {
        private const val TAG = "SystemAudioRecorder"
    }

    /**
     * 开始录制系统音频
     */
    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    fun startRecording(outputFile: File): Boolean {
        if (isRecording) {
            Log.w(TAG, "Already recording")
            return false
        }

        if (!isSystemAudioCaptureSupported()) {
            Log.e(TAG, "System audio capture not supported on this device")
            return false
        }

        return try {
            // 创建配置
            config = AudioRecordingConfig.fromSettings(settings, mediaProjection)
            audioFile = outputFile

            // 初始化编码器或文件处理器
            if (!initializeOutputHandler(outputFile)) {
                Log.e(TAG, "Failed to initialize output handler")
                return false
            }

            // 创建AudioRecord
            audioRecord = createAudioRecord()
            if (audioRecord == null) {
                Log.e(TAG, "Failed to create AudioRecord")
                return false
            }

            // 开始录制
            audioRecord?.startRecording()
            isRecording = true

            // 启动录制协程
            recordingJob = CoroutineScope(Dispatchers.IO).launch {
                recordAudio()
            }

            Log.d(TAG, "System audio recording started")
            true

        } catch (e: Exception) {
            Log.e(TAG, "Failed to start system audio recording", e)
            stopRecording()
            false
        }
    }

    /**
     * 停止录制
     */
    fun stopRecording() {
        if (!isRecording) return

        isRecording = false
        recordingJob?.cancel()

        try {
            // 停止AudioRecord
            audioRecord?.stop()
            audioRecord?.release()

            // 完成输出处理
            finishOutputHandler()
        } catch (e: Exception) {
            Log.e(TAG, "Error stopping audio recording", e)
        } finally {
            // 释放所有资源
            releaseResources()
            Log.d(TAG, "System audio recording stopped")
        }
    }

    /**
     * 录制音频数据
     */
    private suspend fun recordAudio() {
        val buffer = ByteArray(4096)
        val config = this.config ?: return

        while (isRecording) {
            try {
                currentCoroutineContext().ensureActive()
                val bytesRead = audioRecord?.read(buffer, 0, buffer.size) ?: 0
                if (bytesRead > 0) {
                    processAudioData(buffer, bytesRead)
                }
            } catch (e: Exception) {
                Log.e(TAG, "Error reading audio data", e)
                break
            }
        }
    }

    /**
     * 检查设备是否支持系统音频捕获
     */
    private fun isSystemAudioCaptureSupported(): Boolean {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
    }

    /**
     * 获取录制的音频文件
     */
    fun getAudioFile(): File? = audioFile

    /**
     * 检查是否正在录制
     */
    fun isRecording(): Boolean = isRecording

    /**
     * 初始化输出处理器（AAC编码器或WAV文件处理器）
     */
    private fun initializeOutputHandler(outputFile: File): Boolean {
        val config = this.config ?: return false
        
        return if (config.useAacEncoding) {
            // 使用AAC编码
            audioEncoder = AudioEncoder(outputFile, config.sampleRate, 2)
            audioEncoder?.initialize() ?: false
        } else {
            // 使用WAV格式
            wavFileHandler = WavFileHandler(outputFile, config.sampleRate, 2)
            wavFileHandler?.initialize() ?: false
        }
    }

    /**
     * 创建AudioRecord实例
     */
    private fun createAudioRecord(): AudioRecord? {
        val config = this.config ?: return null
        
        return try {
            val bufferSize = config.calculateBufferSize()
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && config.includeSystemAudio) {
                // Android 10+ 使用AudioPlaybackCapture
                createAudioRecordWithPlaybackCapture(bufferSize)
            } else {
                // 回退到默认音频源
                createDefaultAudioRecord(bufferSize)
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to create AudioRecord", e)
            null
        }
    }

    /**
     * 创建带系统音频捕获的AudioRecord
     */
    private fun createAudioRecordWithPlaybackCapture(bufferSize: Int): AudioRecord? {
        return try {
            val config = this.config ?: return null
            val mediaProjection = config.mediaProjection ?: return null
            
            val playbackConfig = AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
                .addMatchingUsage(AudioAttributes.USAGE_MEDIA)
                .addMatchingUsage(AudioAttributes.USAGE_GAME)
                .addMatchingUsage(AudioAttributes.USAGE_UNKNOWN)
                .build()

            val audioFormat = AudioFormat.Builder()
                .setEncoding(config.audioFormat)
                .setSampleRate(config.sampleRate)
                .setChannelMask(config.channelConfig)
                .build()

            AudioRecord.Builder()
                .setAudioFormat(audioFormat)
                .setBufferSizeInBytes(bufferSize)
                .setAudioPlaybackCaptureConfig(playbackConfig)
                .build()
        } catch (e: Exception) {
            Log.w(TAG, "Failed to create AudioRecord with AudioPlaybackCapture, falling back to DEFAULT", e)
            createDefaultAudioRecord(bufferSize)
        }
    }

    /**
     * 创建默认AudioRecord
     */
    private fun createDefaultAudioRecord(bufferSize: Int): AudioRecord? {
        val config = this.config ?: return null
        
        return AudioRecord(
            MediaRecorder.AudioSource.DEFAULT,
            config.sampleRate,
            config.channelConfig,
            config.audioFormat,
            bufferSize
        )
    }

    /**
     * 处理音频数据
     */
    private fun processAudioData(data: ByteArray, size: Int) {
        if (audioEncoder != null) {
            audioEncoder?.encodePcmData(data, size)
        } else if (wavFileHandler != null) {
            wavFileHandler?.writeAudioData(data, size)
        }
    }

    /**
     * 完成输出处理
     */
    private fun finishOutputHandler() {
        audioEncoder?.finishEncoding()
        wavFileHandler?.finishWriting()
    }

    /**
     * 释放所有资源
     */
    private fun releaseResources() {
        audioRecord = null
        audioEncoder?.release()
        audioEncoder = null
        wavFileHandler?.release()
        wavFileHandler = null
        config = null
        audioFile = null
    }
}
